from flask import Blueprint, g
from flask_login import login_required

from apps.a_common.constants import USER_ID_JWT_COOKIES_KEY
from apps.a_common.db import safe_commit
from apps.a_common.error import NotFound
from apps.a_common.jwt import encode_token
from apps.a_common.log import MyLogger
from apps.a_common.request import assert_params_by_form
from apps.a_common.response import success_response, error_response
from apps.users.exceptions import WrongPassword
from apps.users.forms import LoginForm, SignUpForm, UserInfoEditorForm
from apps.users.helper import create_user, get_permissions_by_user_id, set_user_info_by_form
from apps.users.models import User
from apps.users.serializers import serialize_user, serialize_user_all_info

user_blueprint = Blueprint('user', __name__)
log = MyLogger('user view')


@user_blueprint.route('/users/login/', methods=['POST'])
def _login():
    """
    用户登录
    ---
    tags:
      - user
    parameters:
      - name: username
        in : formData
        type: string
        required: true
        description: 用户昵称
      - name: password
        in : formData
        type: string
        required: true
        description: 用户密码
    """
    if g.user.is_authenticated:
        permissions = get_permissions_by_user_id(g.user.id)
        return success_response(serialize_user(g.user, permissions))
    form = assert_params_by_form(LoginForm)
    user = User.query.filter(User.username == form['username']).first()
    if not user:
        return error_response(NotFound())
    if not user.password_is_true(form['password']):
        return error_response(WrongPassword())
    permissions = get_permissions_by_user_id(user.id)

    response = success_response(serialize_user(user, permissions))
    response.set_cookie(USER_ID_JWT_COOKIES_KEY, encode_token(user.id))
    return response


@user_blueprint.route('/users/', methods=['POST'])
def _sign_up():
    """
    用户注册
    ---
    tags:
      - user
    parameters:
      - name: username
        in : formData
        type: string
        required: true
        description: 用户昵称
      - name: password
        in : formData
        type: string
        required: true
        description: 用户密码
      - name: confirm_password
        in : formData
        type: string
        required: true
        description: 用户密码
    """
    form = assert_params_by_form(SignUpForm)
    user = create_user(form)
    permissions = get_permissions_by_user_id(user.id)

    response = success_response(serialize_user(user, permissions))
    response.set_cookie(USER_ID_JWT_COOKIES_KEY, encode_token(user.id))
    return response


@user_blueprint.route('/users/', methods=['GET'])
@login_required
def _get_user_info():
    """
    用户基本信息
    ---
    tags:
      - user
    """
    permissions = get_permissions_by_user_id(g.user.id)
    return success_response(serialize_user(g.user, permissions))


@user_blueprint.route('/users/', methods=['PUT'])
@login_required
def _put_user_info():
    """
    修改用户信息
    ---
    tags:
      - user
    parameters:
      - name: password
        in : formData
        type: string
        required: false
        description: 用户密码
      - name: nickname
        in : formData
        type: string
        required: false
        description: 用户昵称
      - name: avatar
        in : formData
        type: string
        required: false
        description: 用户头像的url，用户的头像先通过file接口上传，再将url传给后端
      - name: skills
        in : formData
        type: array
        required: false
        description: 员工的技能
      - name: first_name
        in : formData
        type: string
        required: false
        description: 员工的名字的姓
      - name: last_name
        in : formData
        type: string
        required: false
        description: 员工的名字的名
      - name: sex
        in : formData
        type: integer
        required: false
        description: 员工的性别，1为男，2为女
      - name: work_experience
        in : formData
        type: string
        required: false
        description: 员工的性别，1为男，2为女
    """
    form = assert_params_by_form(UserInfoEditorForm)
    user = set_user_info_by_form(g.user, form)
    permissions = get_permissions_by_user_id(user.id)
    safe_commit()
    return success_response(serialize_user_all_info(user, permissions))
